﻿#ifndef IPLUGINPARAM_H
#define IPLUGINPARAM_H

#include <QObject>

#include <QDomComment>
#include <QDomElement>
#include <QImage>
#include <QRectF>
#include <QPoint>
#include <QList>
#include <QMap>
#include <QMultiMap>
#include <QPolygonF>
#include <QMetaType>

#include <opencv2/opencv.hpp>
#include <opencv2/imgproc/types_c.h>

#include "Interface_Global.h"

#include "RoiRectEntity.h"
#include "Polygon.h"
#include "Circular.h"
#include "Line.h"
#include "MapVariable.h"


Q_DECLARE_METATYPE(cv::Mat)

namespace CVV
{

namespace Interface
{

enum RunStatus
{
   NotRunning,
   RunSuccessfully,
   RunError
};



using CVV::Entity::RoiRectEntity;
using CVV::Entity::Polygon;
using CVV::Entity::AbstractEntity;
using CVV::Entity::Circular;
using CVV::Entity::MapVariable;
using CVV::Entity::Line;
/**
 * @brief The IPluginParam class
 *  临时参数 t_ 开始 输出参数 o_ 输入参数 i_
 */
class INTERFACE_EXPORT IPluginParam : public QObject
{
    Q_OBJECT

    Q_PROPERTY(bool IsSuccess  READ getT_isSuccess WRITE setT_isSuccess)
    Q_PROPERTY(QString Error READ getT_error WRITE setT_error)
    Q_PROPERTY(QString ID READ getT_id WRITE setT_id)
    Q_PROPERTY(QString Title READ getT_title WRITE setT_title)
    Q_PROPERTY(QString Code READ getT_code WRITE setT_code)
    Q_PROPERTY(RunStatus Status READ getT_status WRITE setT_status)
    Q_PROPERTY(float ElapsedTime READ getT_elapsedTime WRITE setT_elapsedTime)
    Q_PROPERTY(cv::Mat InputImage READ getT_inputImage WRITE setT_inputImage)
    Q_PROPERTY(cv::Mat SecondInputImage READ getSecondInputImage WRITE setSecondInputImage)
    Q_PROPERTY(cv::Mat Image READ getO_image WRITE setO_image)
    Q_PROPERTY(QString ImageHeader READ getO_imageHeader WRITE setO_imageHeader)
    Q_PROPERTY(QString SelectImagePath READ getO_SelectImagePath WRITE setO_SelectImagePath)
    Q_PROPERTY(QList<std::shared_ptr<AbstractEntity>> DetectRect READ getDetectRectF WRITE setDetectRectF)
    Q_PROPERTY(QList<std::shared_ptr<AbstractEntity>> DetectPolygon READ getDetectPolygon WRITE setDetectPolygon)
    Q_PROPERTY(QList<std::shared_ptr<AbstractEntity>> DetectCircle READ getDetectCircle WRITE setDetectCircle)
    Q_PROPERTY(QList<QPoint> PolygonPoints READ getPolygonPoints WRITE setPolygonPoints)
    Q_PROPERTY(QString PreId READ getPreId WRITE setPreId)
    Q_PROPERTY(double MeanValue READ getMeanValue WRITE setMeanValue)
    Q_PROPERTY(QList<std::shared_ptr<AbstractEntity>> DetectVariable READ getDetectVariable WRITE setDetectVariable)
    Q_PROPERTY(QString SelectTestImagePath READ getSelectTestImagePath WRITE setSelectTestImagePath)
    Q_PROPERTY(bool IsModelData  READ getIsModelData WRITE setIsModelData)
    Q_PROPERTY(int PictureId READ getPictureId WRITE setPictureId)


public:
    explicit IPluginParam(QObject *parent = nullptr);
    Q_INVOKABLE IPluginParam(const IPluginParam &cellParam);
    virtual ~IPluginParam();

    Q_INVOKABLE IPluginParam& operator=(const IPluginParam &cellParam);

    Q_INVOKABLE QString getT_error() const;
    Q_INVOKABLE void setT_error(const QString &value);

    Q_INVOKABLE bool getT_isSuccess() const;
    Q_INVOKABLE void setT_isSuccess(bool value);

    Q_INVOKABLE QString getT_id() const;
    Q_INVOKABLE void setT_id(const QString &value);

    Q_INVOKABLE QString getT_title() const;
    Q_INVOKABLE void setT_title(const QString &value);

    Q_INVOKABLE QString getT_code() const;
    Q_INVOKABLE void setT_code(const QString &value);

    Q_INVOKABLE RunStatus getT_status() const;
    Q_INVOKABLE void setT_status(const RunStatus &value);

    Q_INVOKABLE float getT_elapsedTime() const;
    Q_INVOKABLE void setT_elapsedTime(float value);

    Q_INVOKABLE cv::Mat getT_inputImage() const;
    Q_INVOKABLE void setT_inputImage(const cv::Mat &value);

    Q_INVOKABLE cv::Mat getSecondInputImage() const;
    Q_INVOKABLE void setSecondInputImage(const cv::Mat &value);

    Q_INVOKABLE cv::Mat getO_image() const;
    Q_INVOKABLE void setO_image(const cv::Mat& value);

    Q_INVOKABLE QString getO_imageHeader() const;
    Q_INVOKABLE void setO_imageHeader(const QString &imageHeader);

    Q_INVOKABLE QString getO_SelectImagePath() const;
    Q_INVOKABLE void setO_SelectImagePath(const QString &value);

    Q_INVOKABLE QList<std::shared_ptr<AbstractEntity>> getDetectRectF() const;
    Q_INVOKABLE QList<RoiRectEntity> getActuralDetectRectF() const;
    Q_INVOKABLE QList<QRectF> getQRectF() const;

    Q_INVOKABLE void setDetectRectF(const QList<std::shared_ptr<AbstractEntity>> &value);
    Q_INVOKABLE void setsQRectF(const QList<QRectF> &value);

    Q_INVOKABLE QList<std::shared_ptr<AbstractEntity>> getDetectPolygon() const;
    Q_INVOKABLE QList<Polygon> getActuralDetectPolygon() const;
    Q_INVOKABLE void setDetectPolygon(const QList<std::shared_ptr<AbstractEntity>> &value);

    Q_INVOKABLE QList<std::shared_ptr<AbstractEntity>> getDetectVariable() const;
    Q_INVOKABLE void setDetectVariable(const QList<std::shared_ptr<AbstractEntity>> &value);

    Q_INVOKABLE QList<std::shared_ptr<AbstractEntity>> getDetectCircle() const;
    Q_INVOKABLE QList<Circular> getActuralDetectCircle() const;
    Q_INVOKABLE void setDetectCircle(const QList<std::shared_ptr<AbstractEntity>> &value);

    Q_INVOKABLE QList<QPoint> getPolygonPoints() const;
    Q_INVOKABLE void setPolygonPoints(const QList<QPoint> &value);

    Q_INVOKABLE bool getIsDefect() const;
    Q_INVOKABLE void setIsDefect(bool value);

    Q_INVOKABLE QString getPreId() const;
    Q_INVOKABLE void setPreId(const QString &value);

    Q_INVOKABLE double getMeanValue() const;
    Q_INVOKABLE void setMeanValue(const double &value);
    /**
     * @brief getSelectPathAssociationCode
     * @return
     */
    Q_INVOKABLE QMultiMap<QString, QString> getSelectPathAssociationCode() const;
    Q_INVOKABLE void setSelectPathAssociationCode(const QMultiMap<QString, QString> &value);

    /**
    * @brief getSelectTestImagePath
    * @return
    */
    Q_INVOKABLE QString getSelectTestImagePath() const;

    /**
    * @brief setSelectTestImagePath
    * @param value
    */
    Q_INVOKABLE void setSelectTestImagePath(const QString &value);

    /**
     * @brief getAlgoritmPluginCode
     * @return
     */
    Q_INVOKABLE QString getAlgoritmPluginCode() const;

    QDomElement toDomElement();

    Q_INVOKABLE QList<QPolygonF> getAllQRectPoint() const;
    Q_INVOKABLE QList<QPolygonF> getAllQPolygonPoint() const;
    Q_INVOKABLE QList<QPair<QPointF,float>> getAllQCirclePoint() const;
    Q_INVOKABLE QList<QPair<QPointF,QPair<float,float>>> getAllQCircleRingInfo() const;

    /**
     * @brief getIsModelData 是否模板数据
     * @return
     */
    Q_INVOKABLE bool getIsModelData() const;
    Q_INVOKABLE void setIsModelData(bool value);

    /**
     * @brief getPictureId 图号
     * @return
     */
    Q_INVOKABLE int getPictureId() const;
    Q_INVOKABLE void setPictureId(const int value);

    /**
     * @brief hasDynamicProperty 是否包含动态属性
     * @param name
     * @return
     */
    bool hasDynamicProperty(const QString &name) const;

    /**
     * @brief setDynamicPropertyValue
     * @param mapValue
     */
    void setDynamicPropertyValue(const QMap<QString, QVariant> &mapValue);

    /**
     * @brief getDynamicPropertyValue
     * @param name
     * @return
     */
    QVariant getDynamicPropertyValue(const QString &name) const;

    /**
     * @brief getDynamicProperty
     * @return
     */
    QMap<QString, QVariant> getDynamicProperty() const;

    /**
     * @brief setIsLoopParam 是否是循环传参数
     * @param value
     */
    void setIsLoopParam(bool value);
    bool getIsLoopParam() const;

    /**
     * @brief setIsExamples 是否是案例
     * @param value
     */
    void setIsExamples(bool value);
    bool getIsExamples() const;

    /**
     * @brief resetRunData 重置运行时数据
     */
    virtual void resetRunData();

private:
    /**
     * @brief m_dMeanValue 均值
     */
    double m_dMeanValue;
    /**
     * @brief m_strId 该单元插件Id
     */
    QString m_strId;
    /**
     * @brief m_strTitle 该单元插件标题
     */
    QString m_strTitle;
    /**
     * @brief m_iStatus 该单元运行状态
     */
    RunStatus m_iStatus;
    /**
     * @brief m_strCode 该单元插件code
     */
    QString m_strCode;
    /**
     * @brief m_bIsSuccess 该单元插件是否执行成功
     */
    bool m_bIsSuccess;
    /**
     * @brief m_strError 该单元插件执行不成功错误信息
     */
    QString m_strError;
    /**
     * @brief m_fElapsedTime 该单元耗时ms单位
     */
    float m_fElapsedTime;
    /**
     * @brief m_inputImage 输入图片
     */
    cv::Mat m_inputImage;

    /**
     * @brief m_secondInputImage 输入的第二张图
     */
    cv::Mat m_secondInputImage;

    /**
     * @brief m_outImage 当前插件单元执行完的输出图像信息
     */
    cv::Mat m_outImage;
    /**
     * @brief m_outImageHeader 当前插件单元执行完输出图像头部信息
    */
    QString m_strOutImageHeader;

    /**
     * @brief o_image 默认选中的图片路径，或者用户选中的图片路径
     */
    QString m_strSelectImagePath;

    /**
     * @brief m_detectRect 矩形检测区域.
     * roi插件参数存储的是没有经过仿射矩阵变化的，ResultOutput存储的是变化以后的
     */
    QList<RoiRectEntity> m_detectRectF;

    QList<Polygon> m_detectPolygon;

    QList<Circular> m_detectCircle;
    QList<MapVariable> m_detectVariable;

    /**
     * @brief m_lstPolygonPoints 多边形检测区域
     */
    QList<QPoint> m_lstPolygonPoints;

    /**
     * @brief m_bIsDefect 缺陷检测结果是否为缺陷 true-是缺陷 false-不是缺陷
     */
    std::atomic_bool m_bIsDefect;

    /**
     * @brief m_strPreId 前节点ID
     */
    QString m_strPreId;

    /**
     * @brief m_strPreId 图号
     */
    int m_iPictureId;

    /**
     * @brief m_mapSelectPathAssociationCode  选择路径对应的关联code 路径格式为plugincode.id.propertycode<路径 ， 关联code>
     */
    QMultiMap<QString, QString> m_mapSelectPathAssociationCode;

    QString m_SelectTestImagePath;                          // 选中的测试图片路径
    std::atomic_bool m_bIsModelData;                        // 是否是模板图数据

    QMap<QString, QVariant> m_mapDynamicProperty;           // 动态属性对应的值, 引擎执行时使用<动态属性名， 值>

    std::atomic_bool m_bIsLoopParam;                        // 是否是循环传的参数
    std::atomic_bool m_bIsExamples;                         // 是否是案例
};

}

}
Q_DECLARE_METATYPE(CVV::Interface::RunStatus)
#endif // IPLUGINPARAM_H
